﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Snap.Model;

namespace MarketDataAnalyzer
{
    class Driver
    {
        public static long OneMinuteInTicks = (60 * 10000000);
        public static long FiveMinutesInTicks = (5 * OneMinuteInTicks);
        public static long TenMinutesInTicks = (10 * OneMinuteInTicks);
        public static long ThirtyMinutesInTicks = (30 * OneMinuteInTicks);

        static void Main(string[] args)
        {
            
            var context = new SnapModelContainer();

            // Get a reference mapping of symbols to their associated news item Ids
            var symbolToNewsIdMap = context.NewsToCompanies
                .GroupBy( ntc => ntc.CompanySymbol )
                .ToDictionary( grp => grp.Key, grp => grp.Select( x => x.NewsItemId ).ToList() );

            // Get a reference mapping of newsIds to the NewsItem
            var idToNewsItem = context.NewsItems.ToDictionary( ni => ni.Id, ni => ni );

            // Build a map of Symbols to publication date (in EST)
            var symbolToPublicationDateMap = new Dictionary<string, List<DateTime>>();
            foreach (var symbol in symbolToNewsIdMap.Keys)
            {
                if (!symbolToPublicationDateMap.ContainsKey( symbol ))
                {
                    symbolToPublicationDateMap[symbol] = new List<DateTime>();
                }

                foreach (var id in symbolToNewsIdMap[symbol])
                {
                    symbolToPublicationDateMap[symbol].Add( idToNewsItem[id].PublicationDate.AddHours( -6 ) );
                }
            }

            // Now, figure out the stock price at the time of the news, 1m, 5m, 10m, & 30m later
            foreach (var symbol in symbolToPublicationDateMap.Keys)
            {
                string currentSymbol = symbol;
                foreach (var dateTime in symbolToPublicationDateMap[symbol])
                {
                    var iterationDateTime = dateTime;
                    var currentTicks = iterationDateTime.Ticks;
                    Console.WriteLine( "News for symbol {0} at {1}", currentSymbol, iterationDateTime );
                    var newsTimeQuote = context.Tickers
                        .Where( t => t.CompanySymbol == currentSymbol )
                        .Where( t => t.Tick >= currentTicks )
                        .OrderBy( t => t.Tick )
                        .Select( t => t.BuyPriceAvg )
                        .First();
                    Console.WriteLine("BuyPrice at publication: {0:C4} ({1} ticks)", newsTimeQuote, currentTicks);
                    var oneMinuteQuote = context.Tickers
                        .Where( t => t.CompanySymbol == currentSymbol )
                        .Where( t => t.Tick >= (currentTicks + OneMinuteInTicks) )
                        .OrderBy( t => t.Tick )
                        .Select( t => t.BuyPriceAvg )
                        .First();
                    Console.WriteLine( "BuyPrice at 1m after news: {0:C4} ({1} ticks)", oneMinuteQuote,
                                       currentTicks + OneMinuteInTicks );
                    var fiveMinuteQuote = context.Tickers
                        .Where(t => t.CompanySymbol == currentSymbol)
                        .Where(t => t.Tick >= (currentTicks + FiveMinutesInTicks))
                        .OrderBy(t => t.Tick)
                        .Select(t => t.BuyPriceAvg)
                        .First();
                    Console.WriteLine("BuyPrice at 5m after news: {0:C4} ({1} ticks)", fiveMinuteQuote,
                                       currentTicks + FiveMinutesInTicks);
                    var tenMinuteQuote = context.Tickers
                       .Where(t => t.CompanySymbol == currentSymbol)
                       .Where(t => t.Tick >= (currentTicks + TenMinutesInTicks))
                       .OrderBy(t => t.Tick)
                       .Select(t => t.BuyPriceAvg)
                       .First();
                    Console.WriteLine("BuyPrice at 10m after news: {0:C4} ({1} ticks)", tenMinuteQuote,
                                       currentTicks + TenMinutesInTicks);
                    var thirtyMinuteQuote = context.Tickers
                       .Where(t => t.CompanySymbol == currentSymbol)
                       .Where(t => t.Tick >= (currentTicks + ThirtyMinutesInTicks))
                       .OrderBy(t => t.Tick)
                       .Select(t => t.BuyPriceAvg)
                       .First();
                    Console.WriteLine("BuyPrice at 30m after news: {0:C4} ({1} ticks)", thirtyMinuteQuote,
                                       currentTicks + ThirtyMinutesInTicks);


                    Console.WriteLine();
                }    
            }
            

            Console.WriteLine("Press [Enter] to exit.");
            Console.ReadLine();
        }
    }
}
